package com.movie.service.impl;

import com.movie.entity.Comment;
import com.movie.entity.Movie;
import com.movie.entity.User;
import com.movie.entity.Review;
import com.movie.repository.CategoryRepository;
import com.movie.repository.CommentRepository;
import com.movie.repository.MovieRepository;
import com.movie.repository.UserRepository;
import com.movie.repository.ReviewRepository;
import com.movie.service.StatisticsService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class StatisticsServiceImpl implements StatisticsService {
    
    private final UserRepository userRepository;
    private final MovieRepository movieRepository;
    private final CommentRepository commentRepository;
    private final ReviewRepository reviewRepository;
    private final CategoryRepository categoryRepository;
    
    @Override
    public Map<String, Object> getDashboardStats() {
        log.info("获取仪表板统计数据");
        
        long totalUsers = userRepository.count();
        long totalMovies = movieRepository.count();
        long totalComments = commentRepository.count();
        long totalCategories = categoryRepository.count();
        
        // 今日访问量需要从访问记录表中获取，这里简化处理
        long todayVisits = 150L; // 实际项目中应该从访问记录表中统计
        
        return Map.of(
            "totalUsers", totalUsers,
            "totalMovies", totalMovies,
            "totalCategories", totalCategories,
            "totalComments", totalComments,
            "todayVisits", todayVisits
        );
    }
    
    @Override
    public Map<String, Object> getUserGrowth(String period) {
        log.info("获取用户增长数据: {}", period);
        
        // 简化处理：返回最近6个月的数据
        // 实际项目中应该根据period参数从用户创建时间统计
        String[] labels = {"1月", "2月", "3月", "4月", "5月", "6月"};
        int[] data = {100, 150, 200, 180, 250, 300};
        
        return Map.of(
            "labels", labels,
            "data", data
        );
    }
    
    @Override
    public Map<String, Object> getMovieStatistics(Map<String, String> params) {
        log.info("获取影片统计数据");
        
        long totalMovies = movieRepository.count();
        
        // 统计已发布和草稿状态的影片数量
        List<Movie> allMovies = movieRepository.findAll();
        long publishedMovies = allMovies.stream()
                .filter(movie -> "published".equals(movie.getStatus()))
                .count();
        long draftMovies = allMovies.stream()
                .filter(movie -> "draft".equals(movie.getStatus()))
                .count();
        
        // 计算平均评分
        double averageRating = allMovies.stream()
                .filter(movie -> movie.getRating() != null)
                .mapToDouble(Movie::getRating)
                .average()
                .orElse(0.0);
        
        return Map.of(
            "totalMovies", totalMovies,
            "publishedMovies", publishedMovies,
            "draftMovies", draftMovies,
            "averageRating", Math.round(averageRating * 10.0) / 10.0
        );
    }
    
    @Override
    public Map<String, Object> getCommentStatistics(Map<String, String> params) {
        log.info("获取评论统计数据");

        String movieIdStr = params != null ? params.get("movieId") : null;
        Long movieId = null;
        try {
            if (movieIdStr != null && !movieIdStr.isBlank()) {
                movieId = Long.parseLong(movieIdStr);
            }
        } catch (NumberFormatException e) {
            log.warn("movieId 参数格式不正确: {}", movieIdStr);
        }

        long totalComments;
        long approvedComments;
        long pendingComments;
        long rejectedComments;

        if (movieId != null) {
            // 按影片维度统计：总评论数通过分页总数获取，审核状态通过 Review 列表计算
            long totalByMovie = commentRepository.findByMovieId(movieId, PageRequest.of(0, 1)).getTotalElements();
            List<Review> reviewsByMovie = reviewRepository.findByMovieId(movieId);

            approvedComments = reviewsByMovie.stream()
                    .filter(r -> "approved".equalsIgnoreCase(r.getStatus()))
                    .count();
            rejectedComments = reviewsByMovie.stream()
                    .filter(r -> "rejected".equalsIgnoreCase(r.getStatus()))
                    .count();
            long pendingFromReviews = reviewsByMovie.stream()
                    .filter(r -> "pending".equalsIgnoreCase(r.getStatus()))
                    .count();
            long noReviewCount = totalByMovie - reviewsByMovie.size();

            totalComments = totalByMovie;
            pendingComments = pendingFromReviews + Math.max(noReviewCount, 0);
        } else {
            // 全局维度统计：使用总评论数和全部 Review 列表计算各状态数量
            totalComments = commentRepository.count();
            List<Review> allReviews = reviewRepository.findAll();

            approvedComments = allReviews.stream()
                    .filter(r -> "approved".equalsIgnoreCase(r.getStatus()))
                    .count();
            rejectedComments = allReviews.stream()
                    .filter(r -> "rejected".equalsIgnoreCase(r.getStatus()))
                    .count();
            long pendingFromReviews = allReviews.stream()
                    .filter(r -> "pending".equalsIgnoreCase(r.getStatus()))
                    .count();
            long noReviewCount = totalComments - allReviews.size();

            pendingComments = pendingFromReviews + Math.max(noReviewCount, 0);
        }

        return Map.of(
                "totalComments", totalComments,
                "approvedComments", approvedComments,
                "pendingComments", pendingComments,
                "rejectedComments", rejectedComments
        );
    }
    
    @Override
    public Map<String, Object> getSystemUsage() {
        log.info("获取系统使用情况");
        
        // 系统使用情况通常需要从系统监控工具获取
        // 这里返回模拟数据
        return Map.of(
            "cpuUsage", 45.5,
            "memoryUsage", 68.2,
            "diskUsage", 32.1,
            "activeSessions", 25
        );
    }
    
    @Override
    public Map<String, Object> getPopularMovies(Map<String, String> params) {
        log.info("获取热门影片");
        
        // 获取按评分排序的影片
        Pageable pageable = PageRequest.of(0, 10);
        List<Movie> popularMovies = movieRepository.findAll()
                .stream()
                .filter(movie -> movie.getRating() != null)
                .sorted((m1, m2) -> Double.compare(m2.getRating(), m1.getRating()))
                .limit(10)
                .collect(Collectors.toList());
        
        List<Map<String, Object>> movies = popularMovies.stream()
                .map(movie -> {
                    java.util.Map<String, Object> m = new java.util.HashMap<>();
                    m.put("id", movie.getId());
                    m.put("title", movie.getTitle());
                    m.put("rating", movie.getRating() != null ? movie.getRating() : 0.0);
                    return m;
                })
                .toList();
        
        return Map.of("movies", movies);
    }
    
    @Override
    public Map<String, Object> getActiveUsers(Map<String, String> params) {
        log.info("获取活跃用户");
        
        // 获取最近登录的用户
        List<User> allUsers = userRepository.findAll();
        List<Map<String, Object>> users = allUsers.stream()
                .filter(user -> user.getLastLogin() != null)
                .sorted((u1, u2) -> u2.getLastLogin().compareTo(u1.getLastLogin()))
                .limit(10)
                .map(user -> {
                    java.util.Map<String, Object> m = new java.util.HashMap<>();
                    m.put("id", user.getId());
                    m.put("username", user.getUsername());
                    m.put("lastLogin", user.getLastLogin() != null ? user.getLastLogin().toString() : null);
                    return m;
                })
                .toList();
        
        return Map.of("users", users);
    }
}